package com.scj.vue3springboot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scj.vue3springboot.entity.SysRole;
import com.scj.vue3springboot.entity.SysUser;
import com.scj.vue3springboot.entity.SysUserRole;
import com.scj.vue3springboot.entity.vo.LoginVo;
import com.scj.vue3springboot.entity.vo.MenuVo;
import com.scj.vue3springboot.entity.vo.UserVo;
import com.scj.vue3springboot.enums.DelFlagEnum;
import com.scj.vue3springboot.enums.ResultCodeEnum;
import com.scj.vue3springboot.enums.StatusEnum;
import com.scj.vue3springboot.enums.UserTypeEnum;
import com.scj.vue3springboot.mapper.SysRoleMapper;
import com.scj.vue3springboot.mapper.SysUserRoleMapper;
import com.scj.vue3springboot.service.SysUserService;
import com.scj.vue3springboot.mapper.SysUserMapper;
import com.scj.vue3springboot.util.DateUtil;
import com.scj.vue3springboot.util.JwtUtils;
import com.scj.vue3springboot.util.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author 86182
 * @description 针对表【sys_user(用户信息表)】的数据库操作Service实现
 * @createDate 2023-10-11 11:09:09
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements SysUserService {

    @Resource
    RedisTemplate<String, String> redisTemplate;

    @Value("${scj.avatar}")
    private String avatar;
    
    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    public Result login(LoginVo loginVo) {
        // 判断验证码和uuid是否为空
        if (!StringUtils.isNotBlank(loginVo.getCache()) || !StringUtils.isNotBlank(loginVo.getUuid())) {
            return Result.failure("验证码不能为空");
        }

        // 获取验证码
        String redisCode = redisTemplate.opsForValue().get(loginVo.getUuid());

        // 判断验证码是否为空或已过期
        if (StringUtils.isBlank(redisCode)) {
            return Result.failure("验证码已过期");
        }

        // 判断验证码是否匹配
        if (!redisCode.equals(loginVo.getCache())) {
            return Result.failure("验证码错误!");
        }

        // 判断用户名是否为空
        if (StringUtils.isBlank(loginVo.getUsername())) {
            return Result.failure("账号不能为空");
        }

        // 根据用户名进行查找数据
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.eq("user_name", loginVo.getUsername());
        SysUser sysUser = baseMapper.selectOne(sysUserQueryWrapper);

        // 判断用户是否存在
        if (sysUser == null) {
            return Result.failure("账号不存在，请先注册。");
        }

        // 判断用户输入的密码和查询出来的密码是否一致
        if (!sysUser.getPassword().equals(loginVo.getPassword())) {
            return Result.failure("密码错误");
        }

        //TODO 登录成功修改最后登录时间和最后登录ip
        sysUser.setLoginDate(DateUtil.getNowDate());
        baseMapper.updateById(sysUser);

        // 如果密码正确，生成token，返回给前端
        return Result.success("登录成功",JwtUtils.genJwtToken(sysUser.getUserId(),loginVo.getUsername()));
    }

    @Override
    public Result info(String token) {
        // 通过token获取用户名
        String username = JwtUtils.validateJWT(token).getClaims().getSubject();

        // 根据用户名进行查找数据
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.eq("user_name",username);
        SysUser sysUser = baseMapper.selectOne(sysUserQueryWrapper);

        // 判断用户是否存在
        if (sysUser == null) {
            return Result.failure(ResultCodeEnum.LOGIN_FAILURE.getCode(),"账号不存在，请先注册。");
        }

        //根据用户id查询用户角色信息
        List<SysRole> sysRoles = sysRoleMapper.findAllRoleByUserId(sysUser.getUserId());
        String[] roleArr = sysRoles.stream()
                .map(SysRole::getRoleName)
                .toArray(String[]::new);

        //根据用户id查询用户按钮
        List<MenuVo> buttons = sysRoleMapper.findAllRouteByUserIdAndMenuType(sysUser.getUserId(), "F");
        String[] buttonArr = buttons.stream()
                .map(MenuVo::getComponent)
                .toArray(String[]::new);

        //根据用户id查询用户路由信息
        List<MenuVo> routes = sysRoleMapper.findAllRouteByUserId(sysUser.getUserId());
        String[] routeArr = routes.stream()
                .map(MenuVo::getComponent)
                .toArray(String[]::new);

        UserVo userVo = new UserVo();
        userVo.setAvatar(sysUser.getAvatar());
        userVo.setUsername(sysUser.getUserName());
        userVo.setNickname(sysUser.getNickName());
        userVo.setRoles(roleArr);
        userVo.setButtons(buttonArr);
        userVo.setRoutes(routeArr);

        return Result.success("获取用户信息成功",userVo);
    }

    @Override
    public Result findAllUserInfo(Integer page, Integer limit, SysUser sysUser) {
        // 构建查询条件
        LambdaQueryWrapper<SysUser> slqw = new LambdaQueryWrapper<>();
        slqw.like(StringUtils.isNotBlank(sysUser.getNickName()), SysUser::getNickName, sysUser.getNickName());
        slqw.like(StringUtils.isNotBlank(sysUser.getPhonenumber()), SysUser::getPhonenumber, sysUser.getPhonenumber());

        // 设置分页信息
        Page<SysUser> pageObject = new Page<>(page, limit);

        // 执行带有分页的查询
        IPage<SysUser> userPage = baseMapper.selectPage(pageObject, slqw);

        // 返回结果
        return Result.success("查询成功", userPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addUser(SysUser sysUser,String token) {
        //判断账号是否存在
        SysUser user = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, sysUser.getUserName()));
        if (user != null) {
            return Result.failure("账号已存在");
        }

        // 通过token获取用户id
        Long tokenUserId= Long.valueOf(JwtUtils.validateJWT(token).getClaims().getId());
        String date = DateUtil.getNowDate();
        sysUser.setDelFlag(DelFlagEnum.NOT_DELETED.getCode());
        sysUser.setAvatar(avatar);
        sysUser.setUserType(UserTypeEnum.NORMAL_USER.getCode());
        sysUser.setCreateBy(tokenUserId);
        sysUser.setCreateTime(date);
        sysUser.setUpdateBy(tokenUserId);
        sysUser.setUpdateTime(date);
        sysUser.setStatus(StatusEnum.NORMAL.getCode());

        System.err.println(sysUser);
        //添加用户操作
        baseMapper.insert(sysUser);
        return Result.success("添加成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateUser(SysUser sysUser,String token) {
        //判断账号是否存在,如果存在则判断是否是当前用户
        SysUser user = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, sysUser.getUserName()));
        if (user != null && !user.getUserId().equals(sysUser.getUserId())) {
            return Result.failure("账号已存在");
        }

        // 通过token获取用户id
        Long tokenUserId= Long.valueOf(JwtUtils.validateJWT(token).getClaims().getId());
        sysUser.setUpdateBy(tokenUserId);
        sysUser.setUpdateTime(DateUtil.getNowDate());

        //修改用户操作
        updateById(sysUser);
        return Result.success("修改成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteUser(Long userId,String token) {
        // 通过token获取用户id
        Long tokenUserId= Long.valueOf(JwtUtils.validateJWT(token).getClaims().getId());
        UpdateWrapper<SysUser> suuw = new UpdateWrapper<>();
        suuw.set("update_by",tokenUserId);
        suuw.set("update_time",DateUtil.getNowDate());
        suuw.set("del_flag",DelFlagEnum.DELETED.getCode());
        suuw.eq("user_id",userId);
        baseMapper.update(null,suuw);
        return Result.success("删除成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteUsers(List<Long> userId, String token) {
        // 通过token获取用户id
        Long tokenUserId= Long.valueOf(JwtUtils.validateJWT(token).getClaims().getId());
        UpdateWrapper<SysUser> suuw = new UpdateWrapper<>();
        suuw.set("update_by",tokenUserId);
        suuw.set("update_time",DateUtil.getNowDate());
        suuw.set("del_flag",DelFlagEnum.DELETED.getCode());
        suuw.in("user_id",userId);
        baseMapper.update(null,suuw);
        return Result.success("删除成功");
    }

    @Override
    public Result findAllRoleAndUserRole(Long userId) {
        QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
        sysRoleQueryWrapper.select("role_id","role_name","create_time","update_time","remark");
        //查询所有角色信息
        List<SysRole> sysRoles = sysRoleMapper.selectList(sysRoleQueryWrapper);
        //查询该用户拥有哪些角色
        List<SysRole> userRoles = sysRoleMapper.findAllRoleByUserId(userId);
        //返回结果
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("sysRoles",sysRoles);
        resultMap.put("userRoles",userRoles);
        return Result.success("查询成功",resultMap);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addUserRole(Long userId, List<Long> roleIdList) {
        //先删除该用户所有角色
        sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId,userId));

        //再添加该用户新的角色
        for (Long roleId : roleIdList) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(roleId);
            sysUserRoleMapper.insert(sysUserRole);
        }

        return Result.success("分配成功");
    }
}




